﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Roguelike
{
    public class GameManager
    {
        int turn = 0;

        // Represents the player
        Player pc;

        // List of all Entity objects in the game
        public List<Entity> entities;

        // List of all entities that need to update each turn, such as enemies
        public List<UpdatingEntity> updatingEntities;

        // Dictionary of entities' x, y coordinates for quick lookup
        public Dictionary<int[], Entity> entityLocations;

        /// <summary>
        /// Constructor for GameManager
        /// </summary>
        public GameManager()
        {
            InitializeConsole();

            entities = new List<Entity>();
            updatingEntities = new List<UpdatingEntity>();
            entityLocations = new Dictionary<int[], Entity>();

            // Creates player object and adds it to the list of entities; x and y are temporary test values
            pc = new Player(3, 2);
            entities.Add(pc);
            updatingEntities.Add(pc);
            entityLocations.Add(new int[] { pc.x, pc.y }, pc);
        }

        /// <summary>
        /// Sets up the console configuration
        /// </summary>
        private void InitializeConsole()
        {
            Console.Title = "Roguelike";
            Console.WindowHeight = 30;
            Console.WindowWidth = 80;
        }

        /// <summary>
        /// Updates the game state for a new turn
        /// </summary>
        /// <param name="inputType"></param>
        /// <param name="keyPressed"></param>
        public void Update(InputInfo currentInput)
        {
            // If the input is a movement command, move the player
            // I'll need to add a case for navigating in a menu if the menu is open
            if (currentInput.type == inputType.move)
            {
                Singleton<MovementManager>.instance.Move(pc, currentInput.value);
            }
            else if (currentInput.type == inputType.action)
            {
                Singleton<ActionManager>.instance.HandleAction(currentInput.value);
            }

            // All entities that need to update do so
            foreach (UpdatingEntity entity in updatingEntities)
            {
                entity.Update();
            }

            // Increment the turn counter
            turn += 1;
        }

        /// <summary>
        /// Tests if an entity is at x, y coordinates
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public bool TestIfEntityAtXY(int x, int y)
        {
            return entityLocations.ContainsKey(new int[] { x, y });
        }

        /// <summary>
        /// Returns the entity at x, y coordinates
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public Entity GetEntityAtXY(int x, int y)
        {
            return entityLocations[new int[] { x, y }];
        }
    }
}
